package com.jia.train.seat.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jia.train.global.enums.BusinessEnum;
import com.jia.train.global.exception.BusinessException;
import com.jia.train.global.page.PageResponse;
import com.jia.train.global.utils.SnowIdUtil;
import com.jia.train.seat.entity.DailyTrainCarriage;
import com.jia.train.seat.entity.DailyTrainCarriageExample;
import com.jia.train.seat.entity.TrainCarriage;
import com.jia.train.seat.entity.TrainCarriageExample;
import com.jia.train.seat.enums.SeatColEnum;
import com.jia.train.seat.mapper.DailyTrainCarriageMapper;
import com.jia.train.seat.mapper.TrainCarriageMapper;
import com.jia.train.seat.request.DailyTrainCarriageQueryRequest;
import com.jia.train.seat.request.DailyTrainCarriageSaveRequest;
import com.jia.train.seat.response.DailyTrainCarriageQueryResponse;
import com.jia.train.seat.response.DailyTrainCarriageSaveResponse;
import com.jia.train.seat.service.DailyTrainCarriageService;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class DailyTrainCarriageServiceImpl implements DailyTrainCarriageService {

    @Resource
    private DailyTrainCarriageMapper dailyTrainCarriageMapper;

    @Resource
    private TrainCarriageMapper trainCarriageMapper;

    public static final Logger logger = LoggerFactory.getLogger(DailyTrainCarriageServiceImpl.class);


    @Override
    public DailyTrainCarriageSaveResponse insert(DailyTrainCarriageSaveRequest request) {
        DailyTrainCarriage dailyTrainCarriage = BeanUtil.copyProperties(request, DailyTrainCarriage.class);
        DateTime now = DateTime.now();

        String seatType = request.getSeatType();
        List<SeatColEnum> colsByType = SeatColEnum.getColsByType(seatType);
        int size = colsByType.size();
        String tripCode = request.getTripCode();
        Integer index = request.getIndex();
        Date date = request.getDate();

        if (ObjectUtil.isEmpty(dailyTrainCarriage.getId())) {
            if (getDailyTrainCarriageCount(date, tripCode, index) > 0) {
                throw new BusinessException(BusinessEnum.CARRIAGE_NUMBER_OF_THE_SAME_TRAIN_ALREADY_EXISTS);
            }
            dailyTrainCarriage.setId(SnowIdUtil.getLongSnowNextId());
            dailyTrainCarriage.setCreateTime(now);
            dailyTrainCarriage.setColCount(size);
            dailyTrainCarriage.setSeatCount(dailyTrainCarriage.getRowCount() * size);
            dailyTrainCarriageMapper.insert(dailyTrainCarriage);
        } else {
            dailyTrainCarriage.setUpdateTime(now);
            dailyTrainCarriageMapper.updateByPrimaryKeySelective(dailyTrainCarriage);
        }

        return BeanUtil.copyProperties(dailyTrainCarriage, DailyTrainCarriageSaveResponse.class);
    }

    @Override
    public PageResponse<DailyTrainCarriageQueryResponse> selectPage(DailyTrainCarriageQueryRequest request) {

        DailyTrainCarriageExample dailyTrainCarriageExample = new DailyTrainCarriageExample();
        // 排序
        dailyTrainCarriageExample.setOrderByClause("date desc,trip_code asc,`index` asc");
        // 条件
        DailyTrainCarriageExample.Criteria criteria = dailyTrainCarriageExample.createCriteria();
        String tripCode = request.getTripCode();
        Date date = request.getDate();
        if (StringUtils.hasText(tripCode)) {
            criteria.andTripCodeEqualTo(tripCode);
        }
        if (ObjectUtil.isNotNull(date)) {
            criteria.andDateEqualTo(date);
        }
        // 构造分页
        PageHelper.startPage(request.getPage(), request.getSize());
        List<DailyTrainCarriage> DailyTrainCarriages = dailyTrainCarriageMapper.selectByExample(dailyTrainCarriageExample);
        PageInfo<DailyTrainCarriage> pageInfo = new PageInfo<>(DailyTrainCarriages);

        List<DailyTrainCarriageQueryResponse> list
                = BeanUtil.copyToList(DailyTrainCarriages, DailyTrainCarriageQueryResponse.class);

        PageResponse<DailyTrainCarriageQueryResponse> pageResponse = new PageResponse<>();
        pageResponse.setTotal(pageInfo.getTotal());
        pageResponse.setList(list);
        return pageResponse;
    }

    @Override
    public void deleteDailyTrainCarriage(Long id) {
        dailyTrainCarriageMapper.deleteByPrimaryKey(id);
    }

    @Override
    public List<DailyTrainCarriage> selectAllByTripCode(String tripCode) {
        DailyTrainCarriageExample dailyTrainCarriageExample = new DailyTrainCarriageExample();
        dailyTrainCarriageExample.setOrderByClause("`index` asc");
        dailyTrainCarriageExample.createCriteria().andTripCodeEqualTo(tripCode);
        return dailyTrainCarriageMapper.selectByExample(dailyTrainCarriageExample);
    }

    @Override
    public void genDailyTrainCarriage(Date date, String tripCode) {

        logger.info("生成日期：{},车次: {} 的车厢信息", DateUtil.formatDate(date), tripCode);

        TrainCarriageExample trainCarriageExample = new TrainCarriageExample();
        trainCarriageExample.setOrderByClause("`index` asc");
        trainCarriageExample.createCriteria()
                .andTripCodeEqualTo(tripCode);

        List<TrainCarriage> trainCarriages
                = trainCarriageMapper.selectByExample(trainCarriageExample);
        if (CollectionUtils.isEmpty(trainCarriages)) {
            logger.info("车次：{}，没有车厢数据，结束生成任务", tripCode);
            return;
        }

        List<DailyTrainCarriage> dailyTrainCarriageList = new ArrayList<>(trainCarriages.size());

        for (TrainCarriage trainCarriage : trainCarriages) {
            DailyTrainCarriage dailyTrainCarriage
                    = BeanUtil.copyProperties(trainCarriage, DailyTrainCarriage.class);
            dailyTrainCarriage.setId(SnowIdUtil.getLongSnowNextId());
            dailyTrainCarriage.setCreateTime(new DateTime());
            dailyTrainCarriage.setDate(date);
            dailyTrainCarriageList.add(dailyTrainCarriage);
        }

        DailyTrainCarriageExample dailyTrainCarriageExample = new DailyTrainCarriageExample();
        DailyTrainCarriageExample.Criteria criteria = dailyTrainCarriageExample.createCriteria();
        criteria.andTripCodeEqualTo(tripCode);
        criteria.andDateEqualTo(date);

        dailyTrainCarriageMapper.deleteByExample(dailyTrainCarriageExample);
        dailyTrainCarriageMapper.batchInsert(dailyTrainCarriageList);
    }

    private long getDailyTrainCarriageCount(Date date, String code, Integer index) {
        DailyTrainCarriageExample dailyTrainCarriageExample = new DailyTrainCarriageExample();
        DailyTrainCarriageExample.Criteria criteria = dailyTrainCarriageExample.createCriteria();
        criteria.andDateEqualTo(date);
        criteria.andTripCodeEqualTo(code);
        criteria.andIndexEqualTo(index);
        return dailyTrainCarriageMapper.countByExample(dailyTrainCarriageExample);
    }

    public List<DailyTrainCarriage> queryDailyTrainCarriage(Date date, String code, String seatType) {
        DailyTrainCarriageExample dailyTrainCarriageExample = new DailyTrainCarriageExample();
        DailyTrainCarriageExample.Criteria criteria = dailyTrainCarriageExample.createCriteria();
        criteria.andDateEqualTo(date);
        criteria.andTripCodeEqualTo(code);
        criteria.andSeatTypeEqualTo(seatType);
        return dailyTrainCarriageMapper.selectByExample(dailyTrainCarriageExample);
    }

}
